﻿using Autofac;
using DevExpress.Mvvm.UI; 
using Serilog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Threading; 

namespace WpfApp1
{
    public class DIContainerBuilder
    {
        private readonly ContainerBuilder _builder = new();
        private IContainer _container;
        private ILogger _logger;

        /// <summary>
        /// 要注入包含View的Dll
        /// </summary>
        string[] RegViewModelDlls = new string[]
        {
            "WpfApp1.dll",
        };
        /// <summary>
        /// 要注入包含服务的Dll
        /// </summary>
        string[] RegInterfaceDlls = new string[]
        {
            "WpfApp1.dll",
        };

        /// <summary>
        /// 创建Container
        /// </summary>
        /// <returns></returns>
        public IContainer GetBuiltContainer()
        {
            RegisterLogger();
            RegisterMainDependencies();
            RegisterUiDependencies();

            _container = _builder.Build();
            DISource.Resolver = Resolve;
            return _container;
        } 
        private void RegisterLogger()
        {
            var logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Logs","log.txt");
            Directory.CreateDirectory(Path.GetDirectoryName(logPath) ?? "");
            _logger = new LoggerConfiguration()
           .MinimumLevel.Debug()
           .WriteTo.File(logPath, rollingInterval: RollingInterval.Day)
           .WriteTo.Console()
           .WriteTo.Debug()
           .CreateLogger();

            _builder.RegisterInstance(_logger).As<ILogger>().SingleInstance();
        }
        private void RegisterMainDependencies()
        {
            _builder.RegisterInstance(Dispatcher.CurrentDispatcher).AsSelf().SingleInstance();
            _builder.RegisterType<ExceptionHandler>().AsSelf().SingleInstance();
        }
        private void RegisterUiDependencies()
        {
            #region 注册接口
            foreach (var item in RegInterfaceDlls)
            {
                var dllName = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, item);
                if (!File.Exists(dllName))
                {
                    continue;
                }
                var assemblysApplication = Assembly.LoadFrom(dllName);
                _builder.RegisterAssemblyTypes(assemblysApplication)
                     .AsImplementedInterfaces()
                     .InstancePerDependency();
            }
            #endregion

            #region 注册View&ViewModel
            var assemblies = new List<Assembly>
            {
                typeof(App).Assembly
            };
            foreach (var item in RegViewModelDlls)
            {
                var dllName = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, item);
                if (!File.Exists(dllName))
                {
                    continue;
                }
                var assemblysApplication = Assembly.LoadFrom(dllName);
                _builder.RegisterAssemblyTypes(assemblysApplication)
                     .Where(x => x != null && x.Name.EndsWith("ViewModel"))
                     .AsSelf()
                     .AsImplementedInterfaces()
                     .PropertiesAutowired()
                     .InstancePerDependency();

                if(assemblies.Contains(assemblysApplication)) 
                {
                    continue;
                }
                assemblies.Add(assemblysApplication);
            }
            ViewLocator.Default = new ViewLocator(assemblies.ToArray());
            #endregion
        }      
        private object Resolve(Type type, object key, string name)
        {
            if (type == null)
                return null;
            if (key != null)
                return _container.ResolveKeyed(key, type);
            if (name != null)
                return _container.ResolveNamed(name, type);
            return _container.Resolve(type);
        }
    }
}
